﻿using NUnit.Framework;
using Sasa.QualityTools.CodeAnalysis.SearchEngine.Processing;
using Sasa.QualityTools.CodeAnalysis.SearchEngine.Processing.Tokens;
using Sasa.QualityTools.CodeAnalysis.SearchEngine.Tests.Unit.Helpers;
using System;
using System.Collections.Generic;

namespace Sasa.QualityTools.CodeAnalysis.SearchEngine.Tests.Unit.Processing
{
    [TestFixture]
    public class ParserTest
    {
        private Parser testee;


        [SetUp]
        public void SetUp()
        {
            this.testee = new Parser();
        }

        [Test]
        public void TestParseWithNull()
        {
            CollectionAssert.IsEmpty(this.testee.Parse(null));
        }

        [Test]
        public void TestParseWithEmpty()
        {
            CollectionAssert.IsEmpty(this.testee.Parse(new List<IToken>()));
        }

        [Test]
        public void TestParseWithAndStatement()
        {
            var tokens = Tokens().Word("word1").And("AND").Word("word2");
            var expected = Tokens().Word("word1").Word("word2").And("AND");
            CollectionAssert.AreEqual(expected, this.testee.Parse(tokens));
        }

        [Test]
        public void TestParseWithOrStatement()
        {
            var tokens = Tokens().Word("word1").Or("OR").Word("word2");
            var expected = Tokens().Word("word1").Word("word2").Or("OR");
            CollectionAssert.AreEqual(expected, this.testee.Parse(tokens));
        }

        [Test]
        public void TestParseWithAndOrStatement()
        {
            var tokens = Tokens().Word("word1").And("AND").Word("word2").Or("OR").Word("word3");
            var expected = Tokens().Word("word1").Word("word2").And("AND").Word("word3").Or("OR");
            CollectionAssert.AreEqual(expected, this.testee.Parse(tokens));
        }

        [Test]
        public void TestParseWithOrAndStatement()
        {
            var tokens = Tokens().Word("word1").Or("OR").Word("word2").And("AND").Word("word3");
            var expected = Tokens().Word("word1").Word("word2").Word("word3").And("AND").Or("OR");
            CollectionAssert.AreEqual(expected, this.testee.Parse(tokens));
        }

        [Test]
        public void TestParseWithParentheticOrAndStatement()
        {
            var tokens = Tokens().LPar().Word("word1").Or("OR").Word("word2").RPar().And("AND").Word("word3");
            var expected = Tokens().Word("word1").Word("word2").Or("OR").Word("word3").And("AND");
            CollectionAssert.AreEqual(expected, this.testee.Parse(tokens));
        }

        [Test]
        public void TestParseWithComplexStatement()
        {
            var tokens = Tokens()
                .LPar().Word("word1").Or("OR").Word("word2").RPar().And("AND")
                .LPar().Word("word3").Or("OR").Word("word4").RPar().And("AND")
                .Word("word5");
            var expected = Tokens()
                .Word("word1").Word("word2").Or("OR")
                .Word("word3").Word("word4").Or("OR")
                .And("AND").Word("word5").And("AND");
            CollectionAssert.AreEqual(expected, this.testee.Parse(tokens));
        }

        private IEnumerable<IToken> Tokens()
        {
            return new List<IToken>();
        }
    }
}
